package world.ztomorrow.jzyhainan.service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import world.ztomorrow.jzyhainan.common.AnalysisService;
import world.ztomorrow.jzyhainan.domain.HnAdmissionMajor;
import world.ztomorrow.jzyhainan.domain.HnAdmissionProfile;
import world.ztomorrow.jzyhainan.mapper.HnAdmissionMajorMapper;
import world.ztomorrow.jzyhainan.mapper.HnAdmissionProfileMapper;

import java.time.Duration;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class HaiNanServiceImp implements AnalysisService {

    private final HnAdmissionProfileMapper hnAdmissionProfileMapper;
    private final HnAdmissionMajorMapper hnAdmissionMajorMapper;
    /**
     *    "北京", "天津", "河北", "山西", "内蒙古",
     *             "辽宁", "吉林", "黑龙江", "上海", "江苏",
     *             "浙江", "安徽", "福建", "江西", "山东",
     *             "河南", "湖北", "湖南", "广东", "广西",
     *             "海南", "重庆", "四川", "贵州", "云南",
     *             "西藏", "陕西", "甘肃", "青海", "宁夏",
     *             "新疆", "台湾", "香港"
     */
    private static final String[] provinceToSelect = {
                    "北京", "天津", "河北", "山西", "内蒙古"

};
    @Transactional
    @Override
    public void work(WebDriver driver) {
        List<String> profiles = new ArrayList<>();
        List<String> majors = new ArrayList<>();
        List<HnAdmissionProfile> profileList = new ArrayList<>();
        List<HnAdmissionMajor> majorList = new ArrayList<>();

        select(driver, profiles, majors);
        // 获取录取概况
        for (String profile : profiles) {
            profileList.addAll(proFile(profile));
        }
        // 获取分专业录取情况
        for (String major : majors) {
            majorList.addAll(major(major));
        }

        driver.quit();

        // 添加到数据库
        hnAdmissionProfileMapper.insert(profileList);
        hnAdmissionMajorMapper.insert(majorList);
    }

    /**
     *  模拟点击筛选按钮
     */
    private void select(WebDriver driver, List<String> profiles, List<String> majors) {
        try {
            // 创建 WebDriverWait 对象，设置等待时间为10秒
            WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));

            // 1. 选择省份 (`ssmc`)
            for (String province : provinceToSelect) {
                selectElementByCss(driver, wait, "dd[data-param='ssmc'] a[data-value='%s']", province);
                log.info("选择省份：{}", province);

                // 2. 选择年份 (`zsnf`)
                List<String> yearList = getElementsText(wait, "dd[data-param='zsnf']");
                for (String year : yearList) {
                    selectElementByCss(driver, wait, "dd[data-param='zsnf'] a[data-value='%s']", year);
                    log.info("选择年份：{}", year);

                    // 3. 选择科类 (`klmc`)
                    List<String> classList = getElementsText(wait, "dd[data-param='klmc']");
                    for (String clazz : classList) {
                        selectElementByCss(driver, wait, "dd[data-param='klmc'] a[data-value='%s']", clazz);
                        log.info("选择科类：{}", clazz);

                        // 4. 选择招生类型 (`zslx`)
                        List<String> typeList = getElementsText(wait, "dd[data-param='zslx']");
                        for (String type : typeList) {
                            selectElementByCss(driver, wait, "dd[data-param='zslx'] a[data-value='%s']", type);
                            log.info("选择招生类型：{}", type);

                            // 等待更新后的表格
                            addTableToProfilesAndMajors(wait, profiles, majors);
                        }
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 选择元素的辅助方法
     */
    private void selectElementByCss(WebDriver driver, WebDriverWait wait, String cssSelector, String value) {
        WebElement typeElement = wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector(String.format(cssSelector, value))));
        try {
            if (typeElement.isDisplayed() && typeElement.isEnabled()) {
                typeElement.click();
            } else {
                log.warn("Element not clickable: {}", typeElement);
            }
        } catch (Exception ex) {
            log.error("Error clicking element: {}", ex.getMessage());
            // 可选：等待一段时间再重试
        }
    }

    /**
     * 获取元素文本的辅助方法
     */
    private List<String> getElementsText(WebDriverWait wait, String cssSelector) {
        return wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(cssSelector)))
                .findElements(By.cssSelector("a"))
                .stream()
                .map(WebElement::getText)
                .map(String::trim)
                .toList();
    }

    /**
     * 添加表格内容到 profiles 和 majors 的辅助方法
     */
    private void addTableToProfilesAndMajors(WebDriverWait wait, List<String> profiles, List<String> majors) {
        String profileTable = wait.until(ExpectedConditions.presenceOfElementLocated(By.id("zsSsgradeListPlace"))).getAttribute("outerHTML");
        String majorTable = wait.until(ExpectedConditions.presenceOfElementLocated(By.id("sszygradeListPlace"))).getAttribute("outerHTML");
        profiles.add(profileTable);
        majors.add(majorTable);
    }

    /**
     *  解析录取概况表
     */
    private List<HnAdmissionProfile> proFile(String profileStr) {
        List<HnAdmissionProfile> profiles = new ArrayList<>();

        // 使用 Jsoup 解析 HTML
        Document doc = Jsoup.parse(profileStr);
        Element table = doc.getElementById("zsSsgradeListPlace");
        if (table == null) {
            log.error("未找到录取概况表格");
            return profiles;
        }
        Elements rows = table.select("tbody > tr");

        // 遍历表格的每一行
        for (Element row : rows) {
            Elements cols = row.select("td");

            if (cols.size() != 10) {
                continue;
            }
            // 创建新的 HnAdmissionProfile 对象并填充数据
            HnAdmissionProfile profile = new HnAdmissionProfile();
            // 判断每列数据并处理
            if (cols.get(0) != null && !cols.get(0).text().trim().isEmpty()) {
                profile.setApYear(Integer.parseInt(cols.get(0).text().trim()));   // 年份
            }
            if (cols.get(1) != null && !cols.get(1).text().trim().isEmpty()) {
                profile.setApCity(cols.get(1).text().trim());                     // 省市
            }
            if (cols.get(2) != null && !cols.get(2).text().trim().isEmpty()) {
                profile.setApClass(cols.get(2).text().trim());                    // 科类
            }
            if (cols.get(3) != null && !cols.get(3).text().trim().isEmpty()) {
                profile.setApType(cols.get(3).text().trim());                     // 类型
            }
            if (cols.get(4) != null && !cols.get(4).text().trim().isEmpty()) {
                profile.setApMin(cols.get(4).text().trim());    // 最低分
            }
            if (cols.get(5) != null && !cols.get(5).text().trim().isEmpty()) {
                profile.setApRank(cols.get(5).text().trim());   // 最低分排名
            }
            if (cols.get(6) != null && !cols.get(6).text().trim().isEmpty()) {
                profile.setApAvg(cols.get(6).text().trim()); // 平均分
            }
            if (cols.get(7) != null && !cols.get(7).text().trim().isEmpty()) {
                profile.setApMax(cols.get(7).text().trim());    // 最高分
            }
            if (cols.get(8) != null && !cols.get(8).text().trim().isEmpty()) {
                profile.setApLine(cols.get(8).text().trim());   // 控制线
            }
            if (cols.get(9) != null && !cols.get(9).text().trim().isEmpty()) {
                profile.setApCount(cols.get(9).text().trim());  // 录取人数
            }

            // 将解析后的对象加入列表
            profiles.add(profile);
        }
        return profiles;
    }

    /**
     *  分专业录取表
     */
    private List<HnAdmissionMajor> major(String majorsStr) {
        List<HnAdmissionMajor> majors = new ArrayList<>();

        // 使用 Jsoup 解析 HTML
        Document doc = Jsoup.parse(majorsStr);
        Element table = doc.getElementById("sszygradeListPlace");
        if (table == null) {
            log.error("未找到分专业录取情况表格");
            return majors;
        }
        Elements rows = table.select("tbody > tr");

        // 遍历表格的每一行
        for (Element row : rows) {
            Elements cols = row.select("td");

            if (cols.size() != 11) {
                continue;
            }
            // 创建新的 HnAdmissionMajor 对象并填充数据
            HnAdmissionMajor major = new HnAdmissionMajor();
            // 健壮性判断，不需要 else
            if (cols.get(0) != null && !cols.get(0).text().trim().isEmpty()) {
                major.setAmYear(Integer.parseInt(cols.get(0).text().trim()));   // 年份
            }
            if (cols.get(1) != null && !cols.get(1).text().trim().isEmpty()) {
                major.setAmCity(cols.get(1).text().trim());                    // 省市
            }
            if (cols.get(2) != null && !cols.get(2).text().trim().isEmpty()) {
                major.setAmClass(cols.get(2).text().trim());                   // 科类
            }
            if (cols.get(3) != null && !cols.get(3).text().trim().isEmpty()) {
                major.setAmType(cols.get(3).text().trim());                    // 类型
            }
            if (cols.get(4) != null && !cols.get(4).text().trim().isEmpty()) {
                major.setAmMajor(cols.get(4).text().trim());                   // 专业
            }
            if (cols.get(5) != null && !cols.get(5).text().trim().isEmpty()) {
                major.setAmMin(cols.get(5).text().trim());   // 最低分
            }
            if (cols.get(6) != null && !cols.get(6).text().trim().isEmpty()) {
                major.setAmRank(cols.get(6).text().trim());  // 最低分排名
            }
            if (cols.get(7) != null && !cols.get(7).text().trim().isEmpty()) {
                major.setAmAvg(cols.get(7).text().trim()); // 平均分
            }
            if (cols.get(8) != null && !cols.get(8).text().trim().isEmpty()) {
                major.setAmMax(cols.get(8).text().trim());   // 最高分
            }
            if (cols.get(9) != null && !cols.get(9).text().trim().isEmpty()) {
                major.setAmLine(cols.get(9).text().trim());  // 控制线
            }
            if (cols.get(10) != null && !cols.get(10).text().trim().isEmpty()) {
                major.setAmCount(cols.get(10).text().trim()); // 录取人数
            }

            // 将解析后的对象加入列表
            majors.add(major);
        }
        return majors;
    }
}
